package com.xuedakun.xasdk.net.volley;

import com.android.volley.toolbox.StringRequest;
import com.xuedakun.xasdk.utils.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by xuedakun on 2017/6/3 15:10
 *
 * @version : v1.0
 * @project : xasdk
 * @Email : dakun611@Gmail.com
 */
abstract class AbstractRequest<R extends BaseResult> {

    /**
     * 请求头信息
     */
    protected HashMap<String, String> headers = new HashMap<>();

    /**
     * 拼接在url后的参数集合
     */
    protected ArrayList<Object> urlArguments = new ArrayList<Object>();

    /**
     * 以key-value形式传递的参数
     */
    protected HashMap<String, Object> arguments = new HashMap<>();

    /**
     * 请求的host
     */
    protected String host;

    /**
     * 请求的接口方法
     */
    protected String method;

    /**
     * 请求回调
     */
    protected final VolleyCallback<R> callback;

    /**
     * 请求主体
     */
    protected StringRequest stringRequest;

    /**
     * 请求主体构造
     *
     * @param host     请求网络接口的host
     * @param method   请求网络接口的方法名
     * @param callback 请求回调
     */
    public AbstractRequest(String host, String method, VolleyCallback<R> callback) {
        this.host = host;
        this.method = method == null ? "" : method;
        this.callback = callback;
    }

    /**
     * 返回StringRequest主体
     *
     * @return
     */
    protected abstract StringRequest getRealRequest();

    /**
     * 返回最终请求的url
     *
     * @return
     */
    protected abstract String getUrl();

    /**
     * 添加头信息
     *
     * @param key
     * @param header
     * @return
     */
    public AbstractRequest addHeader(String key, String header) {
        headers.put(key, header);
        return this;
    }

    /**
     * 添加多个头信息
     *
     * @param header
     * @return
     */
    public AbstractRequest addHeaders(Map<String, String> header) {
        for (Map.Entry<String, String> entry : header.entrySet()) {
            addHeader(entry.getKey(), entry.getValue());
        }
        return this;
    }

    /**
     * 增加URL中的请求参数，会以URL/Argument1/Argument2的形式组合到URL中
     * 如果在此处传入的参数为数组或者集合，将自动转换为其中元素加下划线结合的形式
     * 例如{1,2,3}将转换为 1_2_3
     *
     * @param argument 请求参数value
     * @return 对象自身
     */
    public AbstractRequest addUrlArgument(Object argument) {
        if (!StringUtils.isObjectToStringNull(argument)) {
            if (argument.getClass().isArray() || argument instanceof Collection) {
                argument = StringUtils.join("_", argument);
            }
            urlArguments.add(argument);
        }
        return this;
    }

    /**
     * 增加请求参数
     *
     * @param key      请求参数key
     * @param argument 请求参数value
     * @return 对象自身
     */
    public AbstractRequest addArgument(String key, Object argument) {
        arguments.put(key, argument);
        return this;
    }

    /**
     * 增加多个请求参数
     *
     * @param arguments
     * @return
     */
    public AbstractRequest addArguments(Map<String, Object> arguments) {
        if (arguments != null) {
            for (Map.Entry<String, Object> entry : arguments.entrySet()) {
                addArgument(entry.getKey(), entry.getValue());
            }
        }
        return this;
    }

    /**
     * 绑定tag，可用于中断请求
     *
     * @param tag
     * @return
     */
    public AbstractRequest addTag(Object tag) {
        getRealRequest().setTag(tag);
        return this;
    }

    /**
     * 添加到volley请求队列,不需要回调
     */
    public void execute() {
        VolleyRequest.getInstance().addRequest(getRealRequest());
    }

    /**
     * 添加回调
     * @param requestCallback
     */
    public void execute(RequestCallback<R> requestCallback) {
        if(callback != null) {
            callback.setRequestCallback(requestCallback);
        }
        execute();
    }
}
